#include "animation.h"

using namespace EPOC;

Animation::Animation()
{
	SetClassID(kCLASSID_ANIMATION);

	m_nLoops = 0;
	m_nAnimationType = kANIMATION_TYPE_NORMAL;
	m_nFrameMode = kANIMATION_FRAMEMODE_NORMAL;
	m_nFrameLimitStart = 0;
	m_nFrameLimitEnd = 0;
	m_fFrameTimer = 0.0f;
	m_fFrameRate = 0;
	m_bReverse = false;
	m_bDone = false;

	SetRemoveWhenDone(false);
	SetFramesEnabled(true);
}

Animation::~Animation()
{
}


bool Animation::Update(float fTimeDelta)
{
	// calculate current frame:

	if(IsDone() == false)
	{
		if(m_fFrameTimer >= 1.0f)
		{
			StepFrame();		
			m_fFrameTimer -= 1.0f;
		}

		// advance animation:
		m_fFrameTimer += m_fFrameRate * fTimeDelta * 0.001f;

		if(CheckFrame() == false)
		{
			m_bDone = true;
			if(IsRemoveWhenDoneEnabled() == true)
				return false;
		}
	}

	return true;
}

void Animation::Reset()
{
	m_fFrameTimer = 0.0f;
	m_bDone = false;

	switch(m_nAnimationType)
	{
		case kANIMATION_TYPE_MANUAL:
		{
			m_nCurrentFrame = 0;
		}
		break;

		case kANIMATION_TYPE_NORMAL:
		case kANIMATION_TYPE_LOOP:
		case kANIMATION_TYPE_PINGPONG:
		{
			if(m_nFrameMode == kANIMATION_FRAMEMODE_NORMAL)
				m_nCurrentFrame = 0;
			else
				m_nCurrentFrame = GetFrameLimitStart();
		}
		break;

		case kANIMATION_TYPE_REVERSE:
		{
			if(m_nFrameMode == kANIMATION_FRAMEMODE_NORMAL)
				m_nCurrentFrame = m_nFrames - 1;
			else
				m_nCurrentFrame = GetFrameLimitEnd();
		}			
		break;
	}

}

void Animation::StepFrame()
{
	switch(m_nAnimationType)
	{
		case kANIMATION_TYPE_NORMAL:
		case kANIMATION_TYPE_LOOP:
		{
			m_nCurrentFrame++;
		}
		break;

		case kANIMATION_TYPE_REVERSE:
		{
			m_nCurrentFrame--;
		}
		break;


		case kANIMATION_TYPE_PINGPONG:
		{
			if(!m_bReverse)
				m_nCurrentFrame++;
			else
				m_nCurrentFrame--;
		}
		break;
	}
}


bool Animation::CheckFrame()
{
	switch(m_nFrameMode)
	{
		case kANIMATION_FRAMEMODE_NORMAL:
		{
			switch(m_nAnimationType)
			{
				case kANIMATION_TYPE_NORMAL:
				{
					if(m_nCurrentFrame >= m_nFrames)
					{
						if(m_nLoops > 0)
						{
							m_nLoops--;
							m_nCurrentFrame = 0;
						}
						else
							return false;
					}
				}
				break;

				case kANIMATION_TYPE_REVERSE:
				{
					if(m_nCurrentFrame <= 0)
					{
						if(m_nLoops > 0)
						{
							m_nLoops--;
							m_nCurrentFrame = m_nFrames - 1;
						}
						else
							return false;
					}

				}
				break;

				case kANIMATION_TYPE_LOOP:
				{
					if(m_nCurrentFrame >= m_nFrames)
					{
						m_nCurrentFrame = 0;
					}
				}
				break;


				case kANIMATION_TYPE_PINGPONG:
				{
					if(m_nCurrentFrame >= m_nFrames && m_bReverse == false)
					{
						m_bReverse = !m_bReverse;
						m_nCurrentFrame = m_nFrames - 2;
					}
					else if(m_nCurrentFrame == 0 && m_bReverse == true)
					{
						m_bReverse = !m_bReverse;
						m_nCurrentFrame = 0;
					}
				}
				break;
			}
		}
		break;

		case kANIMATION_FRAMEMODE_LIMITS:
		{
			switch(m_nAnimationType)
			{
				case kANIMATION_TYPE_NORMAL:
				{
					if(m_nCurrentFrame >= (int) m_nFrameLimitEnd)
					{
						if(m_nLoops > 0)
						{
							m_nLoops--;
							m_nCurrentFrame = (int) m_nFrameLimitStart;
						}
						else
							return false;
					}
				}
				break;

				case kANIMATION_TYPE_REVERSE:
				{
					if(m_nCurrentFrame <= 0)
					{
						if(m_nLoops > 0)
						{
							m_nLoops--;
							m_nCurrentFrame = (int) m_nFrameLimitEnd;
						}
						else
							return false;
					}

				}
				break;

				case kANIMATION_TYPE_LOOP:
				{
					if(m_nCurrentFrame >= (int) m_nFrameLimitEnd)
						m_nCurrentFrame = (int) m_nFrameLimitStart;
				}
				break;


				case kANIMATION_TYPE_PINGPONG:
				{
					if(m_nCurrentFrame >= (int) m_nFrameLimitEnd && m_bReverse == false)
					{
						m_bReverse = !m_bReverse;
						m_nCurrentFrame = (int) m_nFrameLimitEnd - 1;
					}
					else if(m_nCurrentFrame <= (int) m_nFrameLimitStart && m_bReverse == true)
					{
						m_bReverse = !m_bReverse;
						m_nCurrentFrame = (int) m_nFrameLimitStart;
					}
				}
				break;
			}

		}
	}

	return true;
}
